<!-- ImageCropper.vue -->
<template>
    <div class="cropper-wrapper">
      <!-- 上传触发按钮 -->
      <div v-if="!src" class="upload-box" @click="triggerUpload">
        <slot name="trigger">
          <button class="upload-btn">上传图片</button>
        </slot>
        <input 
          ref="fileInput"
          type="file" 
          hidden
          accept="image/*"
          @change="handleFileChange"
        >
      </div>
  
      <!-- 裁剪容器 -->
      <div v-show="src" class="cropper-container">
        <vue-cropper
          ref="cropper"
          :src="src"
          :aspect-ratio="1"
          :view-mode="2"
          :auto-crop-area="0.8"
          :drag-mode="'move'"
          :guides="false"
          :background="false"
          :responsive="true"
          :rotatable="false"
        ></vue-cropper>
  
        <!-- 操作工具栏 -->
        <div class="toolbar">
          <button @click="zoom(-0.1)">➖</button>
          <button @click="zoom(0.1)">➕</button>
          <button @click="rotate(-90)">↩️</button>
          <button @click="rotate(90)">↪️</button>
          <button @click="confirm">确认裁剪</button>
        </div>
      </div>
  
      <!-- 预览区域 -->
      <div v-if="resultUrl" class="preview">
        <img :src="resultUrl" alt="裁剪结果" class="circle-preview">
      </div>
    </div>
  </template>

<script>
import { ref } from 'vue';
import 'vue-cropper/dist/index.css';
import VueCropper from 'vue-cropper';

export default {
  setup() {
    const src = ref('');
    const resultUrl = ref('');
    const cropper = ref(null);
    const fileInput = ref(null);

    const triggerUpload = () => {
      fileInput.value?.click();
    };

    const handleFileChange = (e) => {
      const file = e.target.files?.[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = (e) => {
          src.value = e.target.result;
        };
        reader.readAsDataURL(file);
      }
    };

    const zoom = (delta) => {
      cropper.value?.zoom(delta);
    };

    const rotate = (degree) => {
      cropper.value?.rotate(degree);
    };

    const confirm = () => {
      const canvas = cropper.value?.getCroppedCanvas({
        width: 200,
        height: 200,
        fillColor: 'transparent'
      });

      if (canvas) {
        const roundCanvas = document.createElement('canvas');
        const ctx = roundCanvas.getContext('2d');
        roundCanvas.width = 200;
        roundCanvas.height = 200;
        
        ctx.beginPath();
        ctx.arc(100, 100, 100, 0, Math.PI*2);
        ctx.closePath();
        ctx.clip();
        ctx.drawImage(canvas, 0, 0);
        
        roundCanvas.toBlob(blob => {
          if (blob) {
            resultUrl.value = URL.createObjectURL(blob);
            emit('cropped', blob);
          }
        }, 'image/png');
      }
    };

    return {
      src,
      resultUrl,
      cropper,
      fileInput,
      triggerUpload,
      handleFileChange,
      zoom,
      rotate,
      confirm
    };
  },
  props: {
    diameter: {
      type: Number,
      default: 200
    }
  },
  emits: ['cropped']
}
</script>

<style scoped>
.cropper-wrapper {
  max-width: 600px;
  margin: 0 auto;
}

.upload-btn {
  padding: 12px 24px;
  background: #2196F3;
  color: white;
  border: none;
  border-radius: 25px;
  cursor: pointer;
  font-size: 16px;
  transition: all 0.3s;
}

.upload-btn:hover {
  background: #1976D2;
}

.cropper-container {
  position: relative;
  height: 400px;
  margin: 20px 0;
}

.toolbar {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 15px;
}

.toolbar button {
  padding: 8px 16px;
  background: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.circle-preview {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  box-shadow: 0 2px 12px rgba(0,0,0,0.15);
}
</style>